//
//  SLMP4Parser+Trak.m
//  SLVideoParser
//
//  Created by S_LINE on 2020/6/19.
//  Copyright © 2020 S_LINE. All rights reserved.
//

#import "SLMP4Parser+Trak.h"

#import "SLParserUtil.h"

@implementation SLMP4Parser (Trak)

- (NSDictionary *)tkhdParser:(NSData *)data
{
    if (data.length < 1)
    {
        return nil;
    }
    NSString *versionKey = @"version";
    NSString *flagsKey = @"flags";
    NSString *trackIdKey = @"trackId";
    NSString *durationKey = @"duration";
    NSString *layerKey = @"layer";
    NSString *alternateGroupKey = @"alternateGroup";
    NSString *volumeKey = @"volume";
    NSString *widthKey = @"width";
    NSString *heightKey = @"height";
    NSMutableDictionary *dict = [NSMutableDictionary new];
    NSData *versionData = [data subdataWithRange:NSMakeRange(0, 1)];
    uint64_t version = [SLParserUtil hexToDecimalWithData:versionData];
    [dict setObject:[NSNumber numberWithUnsignedLongLong:version] forKey:versionKey];
    uint64_t offset = 1;
    if (version == 0)
    {
        uint64_t flagsSize = 3;
        NSData *flagsData = [data subdataWithRange:NSMakeRange(offset, flagsSize)];
        uint64_t flags = [SLParserUtil hexToDecimalWithData:flagsData];
        offset += flagsSize;
        // creation time 创建时间（相对于UTC时间1904-01-01零点的秒数）
        uint64_t creationTimeSize = 4;
        offset += creationTimeSize;
        // modification time 修改时间
        uint64_t modificationTimeSize = 4;
        offset += modificationTimeSize;
        // track id id号，不能重复且不能为0
        uint64_t trackIdSize = 4;
        NSData *trackIdData = [data subdataWithRange:NSMakeRange(offset, trackIdSize)];
        uint64_t trackId = [SLParserUtil hexToDecimalWithData:trackIdData];
        offset += trackIdSize;
        // reserved 保留位
        uint64_t reservedSize = 4;
        offset += reservedSize;
        // duration track的时间长度
        uint64_t durationSize = 4;
        NSData *durationData = [data subdataWithRange:NSMakeRange(offset, durationSize)];
        uint64_t duration = [SLParserUtil hexToDecimalWithData:durationData];
        offset += durationSize;
        // reserved 保留位
        reservedSize = 8;
        offset += reservedSize;
        // layer 视频层，默认为0，值小的在上层
        uint64_t layerSize = 2;
        NSData *layerData = [data subdataWithRange:NSMakeRange(offset, layerSize)];
        uint64_t layer = [SLParserUtil hexToDecimalWithData:layerData];
        offset += layerSize;
        // alternate group track分组信息，默认为0表示该track未与其他track有群组关系
        uint64_t alternateGroupSize = 2;
        NSData *alternateGroupData = [data subdataWithRange:NSMakeRange(offset, alternateGroupSize)];
        uint64_t alternateGroup = [SLParserUtil hexToDecimalWithData:alternateGroupData];
        offset += alternateGroupSize;
        // volume 与rate类似，[8.8] 格式，1.0（0x0100）表示最大音量
        uint64_t integerVolumeSize = 1;
        NSData *integerVolumeData = [data subdataWithRange:NSMakeRange(offset, integerVolumeSize)];
        uint64_t integeVolume = [SLParserUtil hexToDecimalWithData:integerVolumeData];
        offset += integerVolumeSize;
        uint64_t floatVolumeSize = 1;
        NSData *floatVolumeData = [data subdataWithRange:NSMakeRange(offset, floatVolumeSize)];
        uint64_t floatVolume = [SLParserUtil hexToDecimalWithData:floatVolumeData];
        offset += floatVolumeSize;
        // reserved 保留位
        reservedSize = 2;
        offset += reservedSize;
        // matrix 视频变换矩阵
        uint64_t matrixSize = 36;
        offset += matrixSize;
        // width 宽，[16.16] 格式值，与sample描述中的实际画面大小比值，用于播放时的展示宽高
        uint64_t integerWidthSize = 2;
        NSData *integerWidthData = [data subdataWithRange:NSMakeRange(offset, integerWidthSize)];
        uint64_t integerWidth = [SLParserUtil hexToDecimalWithData:integerWidthData];
        offset += integerWidthSize;
        uint64_t floatWidthSize = 2;
        NSData *floatWidthData = [data subdataWithRange:NSMakeRange(offset, floatWidthSize)];
        uint64_t floatWidth = [SLParserUtil hexToDecimalWithData:floatWidthData];
        offset += floatWidthSize;
        // height 高，[16.16] 格式值，与sample描述中的实际画面大小比值，用于播放时的展示宽高
        uint64_t integerHeightSize = 2;
        NSData *integerHeightData = [data subdataWithRange:NSMakeRange(offset, integerHeightSize)];
        uint64_t integerHeight = [SLParserUtil hexToDecimalWithData:integerHeightData];
        offset += integerHeightSize;
        uint64_t floatHeightSize = 2;
        NSData *floatHeightData = [data subdataWithRange:NSMakeRange(offset, floatHeightSize)];
        uint64_t floatHeight = [SLParserUtil hexToDecimalWithData:floatHeightData];
        offset += floatHeightSize;
        
        [dict setObject:[NSNumber numberWithUnsignedLongLong:flags] forKey:flagsKey];
        [dict setObject:[NSNumber numberWithUnsignedLongLong:trackId] forKey:trackIdKey];
        [dict setObject:[NSNumber numberWithUnsignedLongLong:duration] forKey:durationKey];
        [dict setObject:[NSNumber numberWithUnsignedLongLong:layer] forKey:layerKey];
        [dict setObject:[NSNumber numberWithUnsignedLongLong:alternateGroup] forKey:alternateGroupKey];
        NSString *volumeString = [NSString stringWithFormat:@"%llu.%llu", integeVolume, floatVolume];
        NSDecimalNumber *volumeNumber = [NSDecimalNumber decimalNumberWithString:volumeString];
        if ([volumeNumber isKindOfClass:[NSNumber class]])
        {
            [dict setObject:volumeNumber forKey:volumeKey];
        }
        NSString *widthString = [NSString stringWithFormat:@"%llu.%llu", integerWidth, floatWidth];
        NSDecimalNumber *widthNumber = [NSDecimalNumber decimalNumberWithString:widthString];
        if ([widthNumber isKindOfClass:[NSNumber class]])
        {
            [dict setObject:widthNumber forKey:widthKey];
        }
        NSString *heightString = [NSString stringWithFormat:@"%llu.%llu", integerHeight, floatHeight];
        NSDecimalNumber *heightNumber = [NSDecimalNumber decimalNumberWithString:heightString];
        if ([heightNumber isKindOfClass:[NSNumber class]])
        {
            [dict setObject:heightNumber forKey:heightKey];
        }
    }
    
    return [dict copy];
}

- (NSDictionary *)elstParser:(NSData *)data
{
    if (data.length < 1)
    {
        return nil;
    }
    NSString *versionKey = @"version";
    NSString *flagsKey = @"flags";
    NSString *entryCountKey = @"entryCount";
    NSString *entryInfoKey = @"entryInfo";
    NSMutableDictionary *dict = [NSMutableDictionary new];
    NSData *versionData = [data subdataWithRange:NSMakeRange(0, 1)];
    uint64_t version = [SLParserUtil hexToDecimalWithData:versionData];
    [dict setObject:[NSNumber numberWithUnsignedLongLong:version] forKey:versionKey];
    uint64_t offset = 1;
    
    if (version == 0)
    {
        uint64_t flagsSize = 3;
        NSData *flagsData = [data subdataWithRange:NSMakeRange(offset, flagsSize)];
        uint64_t flags = [SLParserUtil hexToDecimalWithData:flagsData];
        offset += flagsSize;
        // entry count
        uint64_t entryCountSize = 4;
        NSData *entryCountData = [data subdataWithRange:NSMakeRange(offset, entryCountSize)];
        uint64_t entryCount = [SLParserUtil hexToDecimalWithData:entryCountData];
        offset += entryCountSize;
        
        NSMutableArray *array = [NSMutableArray new];
        // 字节偏移量从文件开始到当前chunk。这个表根据chunk number索引，第一项就是第一个trunk，第二项就是第二个trunk
        for (int i = 0; i < entryCount; i++)
        {
            // Track duration duration of this edit segment in units of the movie’s time scale.
            uint64_t trackDurationSize = 4;
            NSData *trackDurationData = [data subdataWithRange:NSMakeRange(offset, trackDurationSize)];
            uint64_t trackDuration = [SLParserUtil hexToDecimalWithData:trackDurationData];
            offset += trackDurationSize;
            // mediaTime starting time within the media of this edit segment (in media timescale units)。值为-1表示是空edit。Track中的最后一个edit永远不能为空。Any difference between the movie’s duration and the track’s duration is expressed as an implicit empty edit.
            uint64_t mediaTimeSize = 4;
            NSData *mediaTimeData = [data subdataWithRange:NSMakeRange(offset, mediaTimeSize)];
            uint64_t mediaTime = [SLParserUtil hexToDecimalWithData:mediaTimeData];
            offset += mediaTimeSize;
            // mediaRate relative rate at which to play the media corresponding to this edit segment。不能是0或负数
            uint64_t mediaRateSize = 4;
            NSData *mediaRateData = [data subdataWithRange:NSMakeRange(offset, mediaRateSize)];
            uint64_t mediaRate = [SLParserUtil hexToDecimalWithData:mediaRateData];
            offset += mediaRateSize;
            
            [array addObject:@{@"trackDuration": [NSNumber numberWithUnsignedLongLong:trackDuration], @"mediaTime": [NSNumber numberWithUnsignedLongLong:mediaTime], @"mediaRate": [NSNumber numberWithUnsignedLongLong:mediaRate]}];
        }
        
        [dict setObject:[NSNumber numberWithUnsignedLongLong:flags] forKey:flagsKey];
        [dict setObject:[NSNumber numberWithUnsignedLongLong:entryCount] forKey:entryCountKey];
        [dict setObject:array forKey:entryInfoKey];
    }
    
    return [dict copy];
}

@end
